// RotatingTriangle.js (c) 2012 matsuda
// Vertex shader program
var VSHADER_SOURCE = `
attribute vec4 a_Position;
uniform mat4 u_ModelMatrix;
uniform vec4 u_color;
varying vec4 fragColor;
void main() {
  gl_Position = u_ModelMatrix * a_Position;
  fragColor = u_color;
}
`;

// Fragment shader program
var FSHADER_SOURCE = `
precision mediump float;
varying vec4 fragColor;
void main() {
  gl_FragColor = fragColor;
}
`;

// Rotation angle (degrees/second)
var ANGLE_STEP = 45.0;

function main() {
  // Retrieve <canvas> element
  var canvas = document.getElementById("webgl");

  // Get the rendering context for WebGL
  var gl = getWebGLContext(canvas);
  if (!gl) {
    console.log("Failed to get the rendering context for WebGL");
    return;
  }

  // Initialize shaders
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log("Failed to intialize shaders.");
    return;
  }

  // Write the positions of vertices to a vertex shader
  var n = initVertexBuffers(gl);
  if (n < 0) {
    console.log("Failed to set the positions of the vertices");
    return;
  }

  // Specify the color for clearing <canvas>
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  // Get storage location of u_ModelMatrix
  var u_ModelMatrix = gl.getUniformLocation(gl.program, "u_ModelMatrix");
  if (!u_ModelMatrix) {
    console.log("Failed to get the storage location of u_ModelMatrix");
    return;
  }

  // Get storage location of u_ModelMatrix
  var u_color = gl.getUniformLocation(gl.program, "u_color");
  if (!u_color) {
    console.log("Failed to get the storage location of u_color");
    return;
  }

  // Current rotation angle
  var currentAngle = 0.0;
  var r = Math.random(1) * 255;
  var g = Math.random(1) * 255;
  var b = Math.random(1) * 255;
  
  // Model matrix
  var modelMatrix = new Matrix4();

  // Start drawing
  
  var tick = function (dt) {
    // console.log(dt);
    let result = animate(currentAngle, r, g, b); // Update the rotation angle
    currentAngle = result.angle;
    r = result.r;
    g = result.g;
    b = result.b;
    draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix, u_color, r, g, b); // Draw the triangle
    requestAnimationFrame(tick, canvas); // Request that the browser calls tick
  };
  tick();
}

function initVertexBuffers(gl) {
  var vertices = new Float32Array([0, 0.5, -0.5, -0.5, 0.5, -0.5]);
  var n = 3; // The number of vertices

  // Create a buffer object
  var vertexBuffer = gl.createBuffer();
  if (!vertexBuffer) {
    console.log("Failed to create the buffer object");
    return -1;
  }

  // Bind the buffer object to target
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  // Write date into the buffer object
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  // Assign the buffer object to a_Position variable
  var a_Position = gl.getAttribLocation(gl.program, "a_Position");
  if (a_Position < 0) {
    console.log("Failed to get the storage location of a_Position");
    return -1;
  }
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

  // Enable the assignment to a_Position variable
  gl.enableVertexAttribArray(a_Position);

  return n;
}

function draw(
  gl,
  n,
  currentAngle,
  modelMatrix,
  u_ModelMatrix,
  u_color,
  r,
  g,
  b
) {
  // Set the rotation matrix
  modelMatrix.setRotate(currentAngle, 0, 0, 1); // Rotation angle, rotation axis (0, 0, 1)

  // Pass the rotation matrix to the vertex shader
  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  gl.uniform4fv(u_color, [r / 255.0, g / 255.0, b / 255.0, 1]);
  // Clear <canvas>
  gl.clear(gl.COLOR_BUFFER_BIT);

  // Draw the rectangle
  gl.drawArrays(gl.TRIANGLES, 0, n);
}

// Last time that this function was called
var g_last = Date.now();
function animate(angle, r, g, b) {
  // Calculate the elapsed time
  var now = Date.now();

  var elapsed = now - g_last;
  console.log(elapsed)
  g_last = now;
  // Update the current rotation angle (adjusted by the elapsed time)
  var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
  var newR = r + (ANGLE_STEP * elapsed) / 1000.0;
  var newG = g + (ANGLE_STEP * elapsed) / 1000.0;
  var newB = b + (ANGLE_STEP * elapsed) / 1000.0;
  return {
    angle: (newAngle %= 360),
    r: (newR %= 255),
    g: (newG %= 255),
    b: (newB %= 255),
  };
}
